package com.security.manage.search.controller;


import com.security.manage.search.model.*;
import com.security.manage.search.repository.ComputerInfoRepository;
import com.security.manage.search.repository.FileInfoRepository;
import com.security.manage.search.repository.FireWalInfoRepository;
import com.security.manage.search.repository.LogInfoRepository;
import com.security.manage.search.service.UserMicroService;
import com.security.manage.search.util.FastDfsClient;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipInputStream;

@RestController
public class FileUploadController {

    @Resource
    private FastDfsClient fastDfsClient;

    @Resource
    private FileInfoRepository fileInfoRepository;

    @Resource
    private ComputerInfoRepository computerInfoRepository;

    @Resource
    private LogInfoRepository logInfoRepository;

    @Resource
    private UserMicroService userMicroService;

    @Resource
    private FireWalInfoRepository fireWalInfoRepository;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @GetMapping("/file/list")
    public ResData fileList(FileSearchDto fileSearchDto) {

        int page = fileSearchDto.getPage();
        int size = fileSearchDto.getSize();
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        PageRequest of = PageRequest.of(page, size, sort);
        Specification<FileInfo> specification = new Specification<FileInfo>() {
            @Override
            public Predicate toPredicate(Root<FileInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();

                if (StringUtils.isNotEmpty(fileSearchDto.getDeptIds())) {
                    CriteriaBuilder.In<Long> in = criteriaBuilder.in(root.get("deptId").as(Long.class));
                    for (String id : fileSearchDto.getDeptIds().split(",")) {
                        in.value(Long.parseLong(id));
                    }
                    predicateList.add(in);
                }

                if (fileSearchDto.getUserId() != null && fileSearchDto.getUserId() != 0L) {
                    predicateList.add(criteriaBuilder.equal(root.get("userId").as(Long.class), fileSearchDto.getUserId()));
                }

                predicateList.add(criteriaBuilder.like(root.get("fileName").as(String.class), "%" + fileSearchDto.getName() + "%"));
                Predicate[] pre = new Predicate[predicateList.size()];
                pre = predicateList.toArray(pre);
                return criteriaQuery.where(pre).getRestriction();
            }
        };
        Page<FileInfo> all = fileInfoRepository.findAll(specification, of);
        Map<String, Object> map = new HashMap<>();
        map.put("total", all.getTotalElements());
        map.put("data", all.get().collect(Collectors.toList()));
        return new ResData(1, "获取成功", map);
    }

    public static byte[] parseHexStr2Byte(String hexStr) {

        if (hexStr.length() < 1)

            return null;

        byte[] result = new byte[hexStr.length() / 2];

        for (int i = 0; i < hexStr.length() / 2; i++) {

            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);

            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);

            result[i] = (byte) (high * 16 + low);

        }

        return result;

    }

    public static String parseByte2HexStr(byte buf[]) {

        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < buf.length; i++) {

            String hex = Integer.toHexString(buf[i] & 0xFF);

            if (hex.length() == 1) {
                hex = '0' + hex;
            }

            sb.append(hex.toUpperCase());

        }

        return sb.toString();

    }

    private static byte[] kSrc = new byte[]{(byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f,
            (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b, (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f};

    private static byte[] kSrc2 = new byte[]{(byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f};

    private static String jiami(String srcStr) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(SECRET_IV.getBytes()));
        try {
            byte[] bytes = cipher.doFinal(srcStr.getBytes("UTF-8"));
            return java.util.Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

        }
        return "";
    }

    private static String jiemi(String jiemi) throws Exception {

        SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(SECRET_IV.getBytes()));
        try {
            byte[] bytes = cipher.doFinal(java.util.Base64.getDecoder().decode(jiemi.getBytes()));
            return new String(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

        }
        return "";
    }

    private static void jiamiFile() throws Exception {

        SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec,new IvParameterSpec(SECRET_IV.getBytes()));
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("D:\\txt_temp\\System1.txt")),"UTF-8"));
            BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\aes_temp\\System1.txt"),"UTF-8"));

            String str1=null;
            while ((str1 = reader.readLine()) != null) {
                byte[] bytes = cipher.doFinal(str1.getBytes("UTF-8"));
                String encode = java.util.Base64.getEncoder().encodeToString(bytes);
                bfw.write(encode);
                bfw.newLine();
                bfw.flush();
            }
            bfw.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static final String SECRET_KEY="01234567890123456789123456123456";
    private static final String SECRET_IV="0000000000000000";

    private static String jiemiFile() throws Exception {

        SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec,new IvParameterSpec(SECRET_IV.getBytes()));
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("D:\\System-utf8-2\\hostinfo.txt")),StandardCharsets.UTF_8));
            BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\System5.txt"), StandardCharsets.UTF_8));
            String text=null;
            int idx =0;
            while ((text = reader.readLine()) != null) {
                if(idx == 0){
                    text = text.substring(1);
                    idx = 2;
                }

                byte[] decode = Base64.getDecoder().decode(text);
                byte[] bytes = cipher.doFinal(decode);

                bfw.write(new String(bytes,"GBK"));
                bfw.newLine();
                bfw.flush();
            }
            bfw.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

        }
        return "";
    }

    private static void fileChange() throws Exception {

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("D:\\txt_temp\\System.txt")),"UTF-16LE"));
            BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\txt_temp\\System1.txt"),"UTF-8"));
            String line = null;
            while((line =reader.readLine()) != null){
                bfw.write(line);
                bfw.newLine();
                bfw.flush();
            }
            bfw.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public static void main(String[] args) throws Exception {
        /*String srcStr = "小花";
        String jiami = jiami(srcStr);
        System.out.println("jiemi::" + jiemi(jiami));*/

        //fileChange();
        /*jiamiFile();
        Thread.sleep(1000);*/
        //jiemiFile();

        /*String md5 = DigestUtils.md5Hex(new FileInputStream("E:\\log\\apigateway\\target\\apigateway-0.0.1-SNAPSHOT.jar"));
        System.out.println(md5);*/
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sdf.parse("1970-01-01 08:00:00").getTime());
    }

    private void parseFireWallFile(ZipInputStream zin, Long userId, Long deptId) {
        InputStreamReader inputStreamReader = new InputStreamReader(zin);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String text = null;
        try {
            Set<FireWallInfo> infos = new HashSet<>();
            while ((text = bufferedReader.readLine()) != null) {
                if ("".equals(text.trim()) || text.trim().startsWith("#")) {
                    continue;
                }
                String[] ss = text.trim().split(" ");
                if (ss.length != 17) {
                    continue;
                }

                if ("UDP".equals(ss[3])) {
                    continue;
                }

                if (ss[5].endsWith(".1")) {
                    continue;
                }

                FireWallInfo wallnfo = new FireWallInfo();
                wallnfo.setDateTime(LocalDateTime.parse(ss[0] + " " + ss[1], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                wallnfo.setAction(ss[2]);
                wallnfo.setProtocal(ss[3]);
                wallnfo.setSrcIp(ss[4]);
                wallnfo.setDestIp(ss[5]);
                if (!"-".equals(ss[6])) {
                    wallnfo.setSrcPort(Integer.parseInt(ss[6]));
                }
                if (!"-".equals(ss[7])) {
                    wallnfo.setDestPort(Integer.parseInt(ss[7]));
                }
                wallnfo.setPath(ss[16]);
                wallnfo.setUserId(userId);
                wallnfo.setDeptId(deptId);

                infos.add(wallnfo);
            }
            System.err.println(" firewall size:" + infos.size());
            if (infos.size() > 0) {
                fireWalInfoRepository.saveAll(infos);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


}
